package Infix2RPM.processor.Stack;

// Infix-RPN conversion using Shunting-Yard algorithm
import java.util.ArrayList;
import java.util.Stack;

import Infix2RPM.processor.Stack.BasicOperand;
import Infix2RPM.processor.Stack.OperatorLookup;


public class Parser {

	public static String[] infixToRPN(final String[] inputTokens) {
		final ArrayList<BasicOperand> rpnOut = new ArrayList<BasicOperand>();
		final Stack<BasicOperand> stack = new Stack<BasicOperand>();
		for (final String token : inputTokens) {
			if (OperatorLookup.isOperator(token)) {
				while (!stack.empty() && OperatorLookup.isOperator(stack.peek().getValue().toString())) {
					if (((OperatorLookup.isAssociative(token, OperatorLookup.LEFT_ASSOC) && (OperatorLookup
							.cmpPrecedence(token, stack.peek().getValue().toString()) <= 0)))
							|| (OperatorLookup.isAssociative(token,
									OperatorLookup.RIGHT_ASSOC) && (OperatorLookup
									.cmpPrecedence(token, stack.peek().getValue().toString()) < 0))) {
						out.add(stack.pop());
						continue;
					}
					break;
				}
				// Push the operand onto the stack
				stack.push(new BasicOperand(token));
			} else if (token.equals("(")) {
				stack.push(token);
			} else if (token.equals(")")) {
				while (!stack.empty() && !stack.peek().equals("(")) {
					out.add(stack.pop());
				}
				stack.pop();
			} else {
				rpnOut.add(token);
			}
		}
		while (!stack.empty()) {
			out.add(stack.pop());
		}
		final String[] output = new String[out.size()];
		return out.toArray(output);
	}
}